package net.xo68.destiny.core.serialize;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import net.xo68.destiny.contract.common.SystemConstants;
import net.xo68.destiny.contract.domain.report.DatagramSerializationException;
import net.xo68.destiny.contract.domain.report.DatagramSerializer;
import net.xo68.destiny.core.util.Base64Utils;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.Charset;

/**
 * 任务处理报文序列化
 * @author wuxie
 * @version 2020-12-7
 */
public class JobHandleDatagramSerializer implements DatagramSerializer {

    private final JavaType javaType;

    private final ObjectMapper mapper;

    private final Charset charset;

    public JobHandleDatagramSerializer(ObjectMapper mapper) {
        this.mapper = mapper;
        this.javaType= TypeFactory.defaultInstance().constructType(Object.class);
        this.charset=Charset.forName(SystemConstants.ENCODE_DEFAULT);
    }

    @Override
    public <T> String serialize(T t) throws DatagramSerializationException {
        if (t == null) {
            return SystemConstants.STRING_EMPTY;
        }

        try {
            byte[] bytes = mapper.writeValueAsBytes(t);
            return Base64Utils.encode(bytes);
        } catch (JsonProcessingException e) {
            throw new DatagramSerializationException("Could not write JSON: " + e.getMessage(), e);
        }
        //return SystemConstants.STRING_EMPTY;
    }

    @Override
    public String decode(String encodeStr) throws DatagramSerializationException {
        return encodeStr;
    }

    @Override
    public <T> T deserialize(String decodeStr, Class<T> clazz) throws DatagramSerializationException {
        if(StringUtils.isBlank(decodeStr)){
            return null;
        }
        try {
            byte[] bytes=Base64Utils.decode(decodeStr);
            if (bytes==null || bytes.length==0) {
                return null;
            }
            return (T) this.mapper.readValue(bytes, 0, bytes.length, javaType);
        } catch (Exception ex) {
            throw new DatagramSerializationException("Could not read JSON: " + ex.getMessage(), ex);
        }
    }
}
